﻿using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.IdentityModel.Logging;

using PLCS.App.Shared.Common;
using PLCS.App.Shared.Models;
using PLCS.Application.Contracts.EquipmentApp.Dtos;
using PLCS.Client.Service.Client;
using PLCS.Domain.Shared.Enums;
using PLCS.Shared.Common.Constant;

using RestSharp;

using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;

namespace PLCS.App.Shared.Views.UserControls.Chlidren;

/// <summary>
/// RGV.xaml 的交互逻辑
/// </summary>
public partial class RGV : UserControl
{
    #region Properties

    // SignalR连接
    //private HubConnection hubConnection;

    //竖放标志
    private bool verticalflag;

    //左右上下侧边框
    public Rectangle leftline = new();

    public Rectangle rightline = new();
    public Rectangle topline = new();
    public Rectangle bottomline = new();

    //Webapi客户端
    public HttpRestClient restClient = new();

    private RequestParam requestParam;
    public SolidColorBrush bg;

    public ICommand Command
    {
        get { return (ICommand)GetValue(CommandProperty); }
        set { SetValue(CommandProperty, value); }
    }

    public static readonly DependencyProperty CommandProperty =
        DependencyProperty.Register("Command", typeof(ICommand), typeof(RGV), new UIPropertyMetadata(null));

    public object CommandParameter
    {
        get { return (object)GetValue(CommandParameterProperty); }
        set { SetValue(CommandParameterProperty, value); }
    }

    // Using a DependencyProperty as the backing store for CommandParameter.  This enables animation,styling,binding,etc...
    public static readonly DependencyProperty CommandParameterProperty =
        DependencyProperty.Register("CommandParameter", typeof(object), typeof(RGV), new UIPropertyMetadata(null));

    /// <summary>
    /// 强制输入事件和属性来自FrameworkElement
    /// </summary>
    public IInputElement CommandTarget
    {
        get { return (IInputElement)GetValue(CommandTargetProperty); }
        set { SetValue(CommandTargetProperty, value); }
    }

    // Using a DependencyProperty as the backing store for CommandTarget.  This enables animation,etc...
    public static readonly DependencyProperty CommandTargetProperty =
        DependencyProperty.Register("CommandTarget", typeof(IInputElement), typeof(RGV), new UIPropertyMetadata(null));

    /// <summary>
    /// 名称
    /// </summary>
    public string SName
    {
        get { return (string)GetValue(SNameProperty); }
        set { SetValue(SNameProperty, value); }
    }

    public static readonly DependencyProperty SNameProperty =
        DependencyProperty.Register("SName", typeof(string), typeof(RGV), new PropertyMetadata("RGV01"));

    #endregion Properties

    #region Constructor

    public RGV()
    {
        InitializeComponent();
        //小手
        Cursor = Cursors.Hand;
        SizeChanged += RGV_SizeChanged;
        //Background = Brushes.DimGray;

        //this.Loaded += RGV_Loaded;
    }

    /// <summary>
    /// 重载鼠标左击时触发事件
    /// </summary>
    /// <param name="e"></param>
    protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
    {
        base.OnMouseLeftButtonDown(e);
        //_eventAggregator.GetEvent<StationEvent>().Publish(SName);
        var command = Command;
        var parameter = CommandParameter;
        var target = CommandTarget;

        var routedCmd = command as RoutedCommand;
        if (routedCmd != null && routedCmd.CanExecute(parameter, target))
        {
            routedCmd.Execute(parameter, target);
        }
        else if (command != null && command.CanExecute(parameter))
        {
            command.Execute(parameter);
        }
    }

    private async void RGV_Loaded(object sender, RoutedEventArgs e)
    {
        await using HubConnection hubConnection = new HubConnectionBuilder()
        .WithUrl(AddressManager.Address + AddressManager.RGVHub)
        .WithAutomaticReconnect()
        .Build();

        hubConnection.KeepAliveInterval = TimeSpan.FromSeconds(5);
        hubConnection.On<string, DeviceStatus>("ChangeStatus", async (name, status) =>
        {
            await System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
            {
                if (name == SName)
                {
                    //设备状态颜色变化
                    switch (status)
                    {
                        case DeviceStatus.空闲:
                            bg = Brushes.DimGray;
                            break;

                        case DeviceStatus.忙碌:
                            bg = new SolidColorBrush(Color.FromRgb(0, 230, 118));// "#ABFF33";
                            break;

                        case DeviceStatus.故障:
                            bg = new SolidColorBrush(Color.FromRgb(255, 61, 0));
                            break;

                        default:
                            bg = Brushes.Transparent;
                            break;
                    }
                    if (this.Background.ToString() != bg.ToString())
                    {
                        Background = bg;
                        //边框颜色变化
                        bottomline.Fill = Brushes.DimGray;
                    }
                }
            }));
        });

        hubConnection.On<string, string>("ChangeLocation", async (name, stationName) =>
        {
            await System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
            {
                if (name == SName)
                {
                    MoveAnimation(stationName);
                }
            }));
        });
        if (hubConnection.State == HubConnectionState.Disconnected)
        {
            await hubConnection.StartAsync();
            await hubConnection.InvokeAsync("InitalStatus", SName);
        }
    }

    #endregion Constructor

    #region Event

    /// <summary>
    /// Size changed event
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void RGV_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        ToolTip = $"RGV:{SName}";
        //LayoutCanvas.Children.Clear();//when size change then clear canvas's children.
        ////draw the border of rgv
        //verticalflag = LayoutCanvas.ActualWidth < LayoutCanvas.ActualHeight ? true : false;

        rotate.Angle = gd.ActualWidth < gd.ActualHeight ? 90 : 0;
        //signal.Background = bg;
        ////左侧竖边
        //leftline = new Rectangle();
        //leftline.Width = 3;
        //leftline.Height = LayoutCanvas.ActualHeight;
        //leftline.Fill = Brushes.DimGray;
        //LayoutCanvas.Children.Add(leftline);
        ////右侧竖边
        //rightline = new Rectangle();
        //rightline.Width = 3;
        //rightline.Height = LayoutCanvas.ActualHeight;
        //rightline.Fill = Brushes.DimGray;
        //rightline.Margin = new()
        //{
        //    Left = LayoutCanvas.ActualWidth - 3
        //};
        //LayoutCanvas.Children.Add(rightline);

        ////上侧橫边
        //topline = new Rectangle();
        //topline.Width = this.LayoutCanvas.ActualWidth;
        //topline.Height = 3;
        //topline.Fill = Brushes.DimGray;
        //LayoutCanvas.Children.Add(topline);
        ////下侧橫边
        //bottomline = new Rectangle();
        //bottomline.Width = this.LayoutCanvas.ActualWidth;
        //bottomline.Height = 3;
        //bottomline.Fill = Brushes.DimGray;

        //bottomline.Margin = new Thickness()
        //{
        //    Top = this.LayoutCanvas.ActualHeight - 3
        //};
        //LayoutCanvas.Children.Add(bottomline);

        ////RGV内工位
        //UniformGrid uniform = new UniformGrid();
        //uniform.Height = this.LayoutCanvas.ActualHeight - 3 > 0 ? LayoutCanvas.ActualHeight - 3 : 2;
        //uniform.Width = this.LayoutCanvas.ActualWidth - 3 > 0 ? LayoutCanvas.ActualWidth - 3 : 2;
        //uniform.Margin = new Thickness(2, 2, 2, 2);
        //requestParam = new RequestParam(Method.Get, $"equipment/bySNo?no={SName}");
        //var apiResponse = await restClient.ExecuteAsync<EquipmentDto>(requestParam);
        //var model = apiResponse.Data;
        //if (model == null) return;
        //if (model.ContainStationNos == null) return;
        //var stations = model.ContainStationNos?.Split(ConstantChar.SplitChar);
        //ConveyorLine station = new();
        //if (verticalflag)
        //{
        //    uniform.Rows = stations.Length;
        //    uniform.Columns = 1;
        //}
        //else
        //{
        //    uniform.Columns = stations.Length;
        //    uniform.Rows = 1;
        //}
        //for (int i = 0; i < stations.Length; i++)
        //{
        //    station = new ConveyorLine();
        //    station.SName = stations[i];
        //    //station.Background = (Brush)new BrushConverter().ConvertFrom("#1E90FF");
        //    station.Background = Brushes.DimGray;
        //    //station.Command = Command;
        //    //station.CommandParameter = $"Station-{stations[i]}";
        //    station.Margin = verticalflag ? new Thickness(0, 10, 0, 10) : new Thickness(10, 0, 10, 0);
        //    uniform.Children.Add(station);
        //}
        //LayoutCanvas.Children.Add(uniform);
    }

    #endregion Event

    #region Animation

    public void MoveAnimation(string stationName)
    {
        var station = GlobalControl.Frame.FindName(stationName) as Control;
        if (station == null) return; if (station.Name == "0") return;
        double tovalue = Canvas.GetTop(station) + station.Height / 2 - this.Height / 2;
        double nowvalue = Canvas.GetTop(this);
        Direction direction = Direction.Y;
        if (!verticalflag)
        {
            tovalue = Canvas.GetLeft(station) + station.Width / 2 - this.Width / 2;
            nowvalue = Canvas.GetLeft(this);
            direction = Direction.X;
        }
        //double time = Math.Abs(tovalue - nowvalue) / 50; // 时间 = 总长/速度
        double time = 0.1;
        AnimationHelper.FloatInElement(tovalue, direction, this, TimeSpan.FromSeconds(time));
    }

    #endregion Animation
}